package com.jubotech.framework.config;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jubotech.business.web.dao.FriendAddLogDao;
import com.jubotech.business.web.domain.*;
import com.jubotech.business.web.domain.vo.WxFriendaddVo;
import com.jubotech.business.web.service.*;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.google.protobuf.util.JsonFormat;
import com.jubotech.framework.common.AutoType;
import com.jubotech.framework.netty.utils.JsonToProtoConverterUtil;
import com.jubotech.framework.netty.utils.MessageUtil;
import com.jubotech.framework.netty.utils.MsgIdBuilder;
import com.jubotech.framework.netty.utils.NettyConnectionUtil;
import com.jubotech.framework.util.DateUtil;

import Jubo.JuLiao.IM.Wx.Proto.OneKeyLikeTask.OneKeyLikeTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.PullFriendAddReqListTask.PullFriendAddReqListTaskMessage;
import Jubo.JuLiao.IM.Wx.Proto.TransportMessageOuterClass.EnumMsgType;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Service
@EnableScheduling
@EnableAsync
@Slf4j
public class TimingTaskService {

    @Autowired
    private EhcacheService ehcacheService;

    @Autowired
    private NettyConnectionUtil nettyConnectionUtil;

    @Autowired
    private TaskTimeService taskTimeService;

    @Autowired
    private TimeTaskDetailsService timeTaskDetailsService;

    @Autowired
    private CircleTaskService circleTaskService;

    @Autowired
    private FriendAddTaskService friendAddTaskService;

    @Autowired
    private SysAutoSettingService sysAutoSettingService;

    @Autowired
    private WxAccountService wxAccountService;

    @Autowired
    private WxContactService wxContactService;


    @Autowired
    private FriendAddLogService friendAddLogService;


    @Autowired
    private WxFriendAddService wxFriendAddService;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private FriendAddLogDao friendAddLogDao;

    /**
     * 每5分钟计算一次
     */
    @Async
    @Scheduled(cron = "0 0/5 * * * ?") // 测试
    public void executeHourTask() {
        try {
//            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//			for (int i = 0; i < 10; i++) {
//				Date start = simpleDateFormat.parse("2025-07-03 " + i + ":00:00");
//				int b=i+1;
//				Date end = simpleDateFormat.parse("2025-07-03 " + b + ":00:00");
//				if (i == 9) {
//					end = simpleDateFormat.parse("2025-07-03 10:00:00");
//				}
//				List<FriendAddLog> wxFriendaddVos = wxFriendAddService.queryFriendAddLog(start, end);
//
//				if (null != wxFriendaddVos && !wxFriendaddVos.isEmpty()) {
//					for (FriendAddLog log : wxFriendaddVos) {
//						log.setCreateTime(end);
//					}
//				}
//				//300次批量插入
//				if(null != wxFriendaddVos && !wxFriendaddVos.isEmpty()) {
//                    int size = wxFriendaddVos.size();
//                    for (int j = 0; j < size; j += 300) {
//                        // 使用Math.min确保endIndex不超过列表大小
//                        int endIndex = Math.min(j + 300, size);
//                        List<FriendAddLog> subList = wxFriendaddVos.subList(j, endIndex);
//                        friendAddLogService.batchInsert(subList);
//                    }
//
//				}
//			}


            Date now = new Date();
            Date end = now;
            Date start = wxFriendAddService.queryLast();
            List<FriendAddLog> wxFriendaddVos = wxFriendAddService.queryFriendAddLog(start, end);
            if (null != wxFriendaddVos && !wxFriendaddVos.isEmpty()) {
                for (FriendAddLog log : wxFriendaddVos) {
                    log.setCreateTime(now);
                }
                int size = wxFriendaddVos.size();
                for (int j = 0; j < size; j += 300) {
                    // 使用Math.min确保endIndex不超过列表大小
                    int endIndex = Math.min(j + 300, size);
                    List<FriendAddLog> subList = wxFriendaddVos.subList(j, endIndex);
                    friendAddLogService.batchInsert(subList);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 每10分钟去查询是否有未自动通过的好友
     */
    @Async
    @Scheduled(cron = "0 0/10 8-22 * * ?") // 测试
    public void executeTaskOfFriendAdd() {
        try {
            Map<String, ChannelHandlerContext> map = NettyConnectionUtil.userId_nettyChannel;
            if (null != map && map.size() > 0) {
                for (Map.Entry<String, ChannelHandlerContext> entry : map.entrySet()) {
                    String key = entry.getKey();
                    SysAutoSetting sys = sysAutoSettingService.findSettingByWcIdAutoType(key, AutoType.AUTOTYPE_FRIENDREQEST);
                    if (null != sys && sys.getState() == 0) {
                        PullFriendAddReqListTaskMessage.Builder bd = PullFriendAddReqListTaskMessage.newBuilder();
                        bd.setWeChatId(key);
                        bd.setStartTime(System.currentTimeMillis() - (24 * 60 * 60 * 1000));
                        PullFriendAddReqListTaskMessage msg = bd.build();
                        MessageUtil.sendMsg(entry.getValue(), EnumMsgType.PullFriendAddReqListTask, null, null, msg);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 每分钟去查询数据库，检查是否有新任务
     */
    @Async
    @Scheduled(cron = "0 0/1 * * * ?") // 测试
    public void executeTask() {
        try {
            checkTask();// 群发类定时任务(群发好友，群发群，发朋友圈)
            sendCircleTask();// 批量发朋友圈任务
            deleteCircleTask();// 删除朋友圈任务
            deleteCircleCommentTask();// 删除朋友圈评论任务
            checkAddFriendTask();// SOP批量加好友定时任务
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Async
    public void checkAddFriendTask() {// 检查加好友任务
        try {
            log.info(LocalDateTime.now() + " 定时任务检查加好友  对应的线程名: " + Thread.currentThread().getName());
            String execute_time = DateUtil.convertDate2String(new Date(), DateUtil.DATE_FORMAT_4);

            // 检查子任务
            List<FriendAddTaskDetails> tasks1 = friendAddTaskService.findFriendAddTaskDetailsByTime(execute_time);
            if (null != tasks1 && tasks1.size() > 0) {
                for (int i = 0; i < tasks1.size(); i++) {
                    FriendAddTaskDetails task = tasks1.get(i);
                    if (null != task) {

                        boolean flag = JsonToProtoConverterUtil.sendAddFriendsTaskMessage(task);
                        if (flag) {
                            task.setState(0);// 修改子任务状态
                            friendAddTaskService.updateDetailState(task);
                            //friendAddTaskService.delete(task);

                            // 修改主任务
                            FriendAddTask faddTask = friendAddTaskService.findFriendAddTaskByid(task.getTid());
                            if (null != faddTask) {
                                Integer doingsize = faddTask.getDoingsize() + 1;
                                faddTask.setDoingsize(doingsize);
                                friendAddTaskService.update(faddTask);
                            }
                        }

                    }
                }
            }

            // 检查主任务
            List<FriendAddTask> tasks = friendAddTaskService.findFriendAddTaskByTime(execute_time);
            if (null != tasks && tasks.size() > 0) {
                // 设置下次执行时间
                Date tomorrow = DateUtil.offsetDay(new Date(), 1);
                execute_time = DateUtil.convertDate2String(tomorrow, DateUtil.DATE_FORMAT_4);
                for (int i = 0; i < tasks.size(); i++) {
                    FriendAddTask task = tasks.get(i);
                    if (null != task) {
                        try {
                            // 创建子任务
                            boolean flag = friendAddTaskService.createTaskDetails(task);
                            // 修改下次执行时间
                            if (flag) {
                                task.setExecute_time(execute_time);
                            } else {
                                task.setState(0);
                            }
                            friendAddTaskService.update(task);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 群发类定时任务
     */
    @Async
    public synchronized void checkTask() {
        try {
            log.info(LocalDateTime.now() + " 群发消息定时任务  对应的线程名: " + Thread.currentThread().getName());
            String execute_time = DateUtil.convertDate2String(new Date(), DateUtil.DATE_FORMAT_4);
            List<TaskTimeInfo> tasks = taskTimeService.findTaskTimeByTime(execute_time);
            if (null != tasks && tasks.size() > 0) {
                for (int i = 0; i < tasks.size(); i++) {
                    TaskTimeInfo task = tasks.get(i);
                    if (null != task) {
                        List<TimeTaskDetails> taskDetails = taskTimeService.findTimeTaskDetailsByTidDate(task.getId(), 1, execute_time);
                        if (null != taskDetails && taskDetails.size() > 0) {
                            for (int j = 0; j < taskDetails.size(); j++) {
                                TimeTaskDetails details = taskDetails.get(j);

                                boolean flag = JsonToProtoConverterUtil.sendProtoMsg(task, taskDetails.get(j));
                                if (flag) {
                                    //是朋友圈周期循环任务，执行时间正确
                                    if (null != task.getCycle_state() && task.getCycle_state() == 1 && !StringUtils.isEmpty(task.getEnd_time())) {
                                        Date date1 = DateUtil.convertString2Date(details.getExecute_time(), DateUtil.DATE_FORMAT_4);//当前子任务执行时间
                                        date1 = DateUtil.offsetDay(date1, 1);
                                        Date endtime = DateUtil.convertString2Date(task.getEnd_time(), DateUtil.DATE_FORMAT_4);//当前任务结束时间
                                        if (endtime.getTime() >= date1.getTime()) {
                                            String sExecute_time = DateUtil.convertDate2String(date1, DateUtil.DATE_FORMAT_4);
                                            task.setExecute_time(sExecute_time);//设置主任务执行时间
                                            details.setExecute_time(sExecute_time);//设置子任务执行时间
                                            details.setState(1);// 修改子任务状态
                                        } else {
                                            details.setState(0);// 修改子任务状态
                                        }

                                        timeTaskDetailsService.updateState(details);//只能改

                                    } else {
                                        details.setState(0);// 修改子任务状态
                                        timeTaskDetailsService.updateState(details);//可改可删
                                        //timeTaskDetailsService.delete(details);//直接删掉
                                    }
                                }
                            }
                        }

                        List<TimeTaskDetails> taskDetails1 = taskTimeService.findTimeTaskDetailsByTid(task.getId());
                        if (null == taskDetails1 || taskDetails1.size() == 0) {
                            task.setState(0);// 修改主任务状态
                        }

                        taskTimeService.updateState(task);

                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            e.printStackTrace();
        }


    }

    /**
     * 批量发朋友圈定时任务
     */
    @Async
    public void sendCircleTask() {
        try {
            log.info(LocalDateTime.now() + " 批量发朋友圈定时任务  对应的线程名: " + Thread.currentThread().getName());

            String execute_time = DateUtil.convertDate2String(new Date(), DateUtil.DATE_FORMAT_4);
            long expire = new Date().getTime() - 1000 * 3600 * 48;
            String expire_time = DateUtil.convertDate2String(new Date(expire), DateUtil.DATE_FORMAT_4);
            List<Integer> taskIds = circleTaskService.findTaskIdByTime(execute_time);
            if (null != taskIds && taskIds.size() > 0) {
                log.info("发朋友圈定时任务数: " + taskIds.size());
                for (int i = 0; i < taskIds.size(); i++) {
                    Integer taskid = taskIds.get(i);
                    if (null != taskid) {
                        List<CircleTaskDetails> taskDetails = circleTaskService.findTimeTaskDetailsByTid(taskid, execute_time, expire_time);
                        if (null != taskDetails && taskDetails.size() > 0) {
                            for (int j = 0; j < taskDetails.size(); j++) {
                                CircleTaskDetails details = taskDetails.get(j);

                                boolean flag = JsonToProtoConverterUtil.sendPostSNSNewsTaskMessage(taskDetails.get(j).getJson_content());
                                if (flag) {
                                    details.setState(0);// 修改子任务状态
                                    circleTaskService.setDetailState(details.getId(), 0);
                                }

                            }
                            List<CircleTaskDetails> taskDetails1 = circleTaskService.findTimeTaskDetailsByTidState(taskid, 1);
                            if (null == taskDetails1 || taskDetails1.size() == 0) {
                                circleTaskService.setTaskState(taskid, 0);// 修改主任务状态
                            }
                        } else {
                            // 清理掉过期的任务
                            //task.setState(0);// 修改主任务状态
                            //circleTaskService.update(task);
                        }

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 删除朋友圈定时任务
     */
    @Async
    public void deleteCircleTask() {
        try {
            log.info(LocalDateTime.now() + " 删除朋友圈定时任务  对应的线程名: " + Thread.currentThread().getName());

            String execute_time = DateUtil.convertDate2String(new Date(), DateUtil.DATE_FORMAT_4);

            List<TimeTaskDetails> taskDetails = taskTimeService.findTimeTaskDetailsByTidDate(0, 1, execute_time);
            if (null != taskDetails && taskDetails.size() > 0) {
                for (int j = 0; j < taskDetails.size(); j++) {
                    TimeTaskDetails details = taskDetails.get(j);
                    boolean flag = JsonToProtoConverterUtil.deleteSNSNewsTaskMessage(taskDetails.get(j));
                    if (flag) {
                        timeTaskDetailsService.delete(details);
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 删除朋友圈评论定时任务
     */
    @Async
    public void deleteCircleCommentTask() {
        try {
            log.info(LocalDateTime.now() + " 删除朋友圈评论定时任务  对应的线程名: " + Thread.currentThread().getName());

            String execute_time = DateUtil.convertDate2String(new Date(), DateUtil.DATE_FORMAT_4);

            List<TimeTaskDetails> taskDetails = taskTimeService.findTimeTaskDetailsByTidDate(-1, 1, execute_time);
            if (null != taskDetails && taskDetails.size() > 0) {
                for (int j = 0; j < taskDetails.size(); j++) {
                    TimeTaskDetails details = taskDetails.get(j);

                    boolean flag = JsonToProtoConverterUtil.deleteCircleCommentMessage(taskDetails.get(j));
                    if (flag) {
                        timeTaskDetailsService.delete(details);
                    }

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 每20秒检查通道是否有效
     */
    @Async
    @Scheduled(cron = "0/30 * * * * ?") // 测试
    public void checkChannel() {
        try {
            log.info(LocalDateTime.now() + "定时任务:检查通道是否有效");
            Map<String, ChannelHandlerContext> map = NettyConnectionUtil.userId_nettyChannel;
            if (null != map && map.size() > 0) {
                Cache cache = ehcacheService.getCache();
                for (Map.Entry<String, ChannelHandlerContext> entry : map.entrySet()) {
                    try {
                        ChannelHandlerContext ctx = entry.getValue();
                        String key = nettyConnectionUtil.getNettyId(ctx);
                        if (null != cache) {
                            Integer value = 0;
                            if (null != cache.get(key)) {
                                value = cache.get(key, Integer.class);
                                if (value > 3) {
                                    nettyConnectionUtil.exit(ctx);
                                    value = 0;
                                } else {
                                    value = value + 1;
                                }
                            }
                            cache.put(key, value);
                            if (value > 1) {
                                log.info("服务端发送心跳 " + key);
                                MessageUtil.sendMsg(ctx, EnumMsgType.HeartBeatReq, null, null, null);
                            }
                        }
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 每天定时执行点赞任务
     */
    @Async
    //@Scheduled(cron = "0 0/1 22 * * ?")
    public void doMomentsPraise() {
        try {
            log.info(LocalDateTime.now() + " 点赞定时任务  对应的线程名: " + Thread.currentThread().getName());
            long execute_long = new Date().getTime();
            List<TimeTaskDetails> details = timeTaskDetailsService.findTimeTaskDetailsByTid(-2);
            if (null != details) {
                for (TimeTaskDetails detail : details) {
                    long details_execute_long = DateUtil
                            .convertString2Date(detail.getExecute_time(), DateUtil.DATE_FORMAT_4).getTime();
                    if (execute_long >= details_execute_long) {
                        boolean flag = JsonToProtoConverterUtil.sendOneKeyLikeTaskMessage(detail);
                        if (flag) {
                            try {
                                timeTaskDetailsService.delete(detail);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 每天定时生成点赞任务
     */
    @Async
    //@Scheduled(cron = "0 50 21 * * ?")
    public void checkMomentsPraise() {
        try {

            log.info(LocalDateTime.now() + " 生成点赞定时任务  对应的线程名: " + Thread.currentThread().getName());
            try {
                timeTaskDetailsService.deleteByTid(-2);
            } catch (Exception e1) {
                e1.printStackTrace();
            }

            Map<String, ChannelHandlerContext> map = NettyConnectionUtil.userId_nettyChannel;
            if (null != map && map.size() > 0) {
                for (Map.Entry<String, ChannelHandlerContext> entry : map.entrySet()) {
                    String key = entry.getKey();
                    SysAutoSetting sys = sysAutoSettingService.findSettingByWcIdAutoType(key,
                            AutoType.AUTOTYPE_MOMENTSPRAISE);
                    if (null != sys) {
                        OneKeyLikeTaskMessage.Builder bd = OneKeyLikeTaskMessage.newBuilder();
                        bd.setWeChatId(key);
                        bd.setTaskId(MsgIdBuilder.getId());
                        bd.setRate(new Random().nextInt(30) + 30);
                        OneKeyLikeTaskMessage msg = bd.build();
                        // MessageUtil.sendMsg(ctx, EnumMsgType.OneKeyLikeTask,null,null, msg);

                        if (null != msg) {
                            try {
                                String json = JsonFormat.printer().print(msg);
                                if (!StringUtils.isEmpty(json)) {
                                    TimeTaskDetails detail = new TimeTaskDetails();
                                    detail.setTid(-2);
                                    detail.setState(1);
                                    detail.setExecute_time(getOneKeyLikeDate());
                                    detail.setJson_content(json);
                                    timeTaskDetailsService.insert(detail);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

                    }
                }
            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 每天定时清理过期的朋友圈任务
     */
    @Async
    @Scheduled(cron = "0 0 2 * * ?")
    public void cleanCircleTask() {
        try {

            log.info(LocalDateTime.now() + " 定时清理过期朋友圈任务");

            long expire = new Date().getTime() - 1000 * 3600 * 48;
            String expire_time = DateUtil.convertDate2String(new Date(expire), DateUtil.DATE_FORMAT_4);
            String min_time = DateUtil.convertDate2String(new Date(0L), DateUtil.DATE_FORMAT_4);
            List<Integer> taskIds = circleTaskService.findTaskIdByTime(expire_time);
            if (null != taskIds && taskIds.size() > 0) {
                for (int i = 0; i < taskIds.size(); i++) {
                    Integer taskid = taskIds.get(i);
                    if (null != taskid) {
                        List<CircleTaskDetails> taskDetails = circleTaskService.findTimeTaskDetailsByTid(taskid, expire_time, min_time);
                        if (null != taskDetails && taskDetails.size() > 0) {
                            for (int j = 0; j < taskDetails.size(); j++) {
                                CircleTaskDetails details = taskDetails.get(j);
                                circleTaskService.setDetailState(details.getId(), 2);
                            }
                        }
                        List<CircleTaskDetails> taskDetails1 = circleTaskService.findTimeTaskDetailsByTidState(taskid, 1);
                        if (null == taskDetails1 || taskDetails1.size() == 0) {
                            circleTaskService.setTaskState(taskid, 2);// 修改主任务状态
                        }
                    }
                }
            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 每天定时删除4天前的无用数据
     */
    @Async
    @Scheduled(cron = "1 0 0 * * ?")
    public void deleteTaskDataByDay() {
        try {

            log.info(LocalDateTime.now() + " 定时删除4天前的无用数据  对应的线程名: " + Thread.currentThread().getName());

            Date date = DateUtil.offsetDay(new Date(), -4);
            String dateStr = DateUtil.convertDate2String(date, DateUtil.DATE_FORMAT_2);

            taskTimeService.deleteTaskDetail(dateStr);

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * 每月定时删除无用数据
     */
    @Async
    //@Scheduled(cron = "0 0 0 1 * ?") //
    public void deleteTaskData() {
        try {

            log.info(LocalDateTime.now() + " 定时删除无用数据  对应的线程名: " + Thread.currentThread().getName());

            Date date = DateUtil.offsetMonth(new Date(), -3);
            String dateStr = DateUtil.convertDate2String(date, DateUtil.DATE_FORMAT_2);

            taskTimeService.deleteTask(dateStr);

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    private static String getOneKeyLikeDate() {
        String ymd = DateUtil.convertDate2String(new Date(), DateUtil.DATE_FORMAT_1);
        Integer mm = new Random().nextInt(59);
        String mmStr = "";
        if (mm < 10) {
            mmStr = "0" + mm;
        } else {
            mmStr = mm + "";
        }
        return ymd + " " + "22:" + mmStr;
    }

}
